// 引入依赖模块
const gulp = require('gulp')
const uglify = require('gulp-uglify')
const babel = require('gulp-babel')
const sass = require('gulp-sass')
const html = require('gulp-htmlmin')
const cleanCss = require('gulp-clean-css')
const del = require('del')
const connect = require('gulp-connect')

// 定义路径，将需要处理文件的路径添加到对应属性中保存
const paths = {
  html: {
    src: 'src/**/*.html',
    dest: 'dist'
  },
  css: {
    src: 'src/css/**/*.css',
    dest: 'dist/css'
  },
  scss: {
    src: 'src/scss/**/*.scss',
    dest: 'dist/css'
  },
  js: { // js 文件路径
    src: 'src/js/**/*.js', // 源代码路径 
    dest: 'dist/js', // 压缩后的目标位置
  },
  libs: {
    src: 'src/libs/**/*.*',
    dest: 'dist/libs'
  },
  images: {
    src: 'src/images/**/*.*',
    dest: 'dist/images'
  }
}

// 定义函数，用于处理 js 压缩任务
function scripts() {
  return gulp.src(paths.js.src, { sourcemaps: true })
    .pipe(babel({ // 转译
      presets: ['env']
    }))
    .pipe(uglify()) // 压缩
    .pipe(gulp.dest(paths.js.dest))
    .pipe(connect.reload())
}

// 定义函数，用于处理 css 资源
function styles() {
  return gulp.src(paths.css.src)
    .pipe(cleanCss())
    .pipe(gulp.dest(paths.css.dest))
    .pipe(connect.reload())
}

// 定义函数，用于处理 scss 编译
function sasses() {
  return gulp.src(paths.scss.src)
    .pipe(sass({outputStyle: 'expanded'}))
    .pipe(gulp.dest(paths.scss.dest))
    .pipe(connect.reload())
}

// 定义函数，用于压缩 html 文件
function htmls() {
  return gulp.src(paths.html.src)
    .pipe(html({collapseWhitespace: true, minifyCSS: true, minifyJS: true}))
    .pipe(gulp.dest(paths.html.dest))
    .pipe(connect.reload())
}

// 定义函数，复制 libs 目录
function copyLibs() {
  return gulp.src(paths.libs.src)
    .pipe(gulp.dest(paths.libs.dest))
}

// 定义函数，复制 images 目录
function copyImages() {
  return gulp.src(paths.images.src)
    .pipe(gulp.dest(paths.images.dest))
}

// 定义函数，清理 dist 目标目录
function clean() {
  return del(['dist'])
}

// 定义启动 webserver 服务器的函数
function server() {
  connect.server({
    root: 'dist',
    livereload: true
  })
}

// 定制 watch 监视任务
function watch() {
  // 监视到 js 文件的修改，则自动执行 js 处理任务
  gulp.watch(paths.js.src, scripts)
  // 监视到 scss 变化，则重新编译 scss
  gulp.watch(paths.scss.src, sasses)
  // 监视到 css 变化，压缩 css
  gulp.watch(paths.css.src, styles)
  // 监视到 html 文件变化，则重新压缩 html
  gulp.watch(paths.html.src, htmls)
}

// 定义私有任务，完成一套工作流程中的所有任务
const build = gulp.series(clean, gulp.parallel(scripts, styles, sasses, htmls, copyLibs, copyImages, watch, server))

// 导出监视任务
// exports.任务名称，如果需要执行指定名称的任务，
// 在命令行中使用 `gulp 任务名称` 来执行。
// 如果不跟任务名称直接执行 `gulp`，则表示执行默认任务
exports.watch = watch

// 导出启动服务器任务
exports.server = server

// 作为默认任务导出
exports.default = build
